home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 23
/
AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso
/
Updates
/
Datatypes
/
PCD-DT
/
Source
/
dispatcher.c
next >
Wrap
C/C++ Source or Header
|
1999-11-14
|
9KB
|
375 lines
#include <clib/alib_protos.h>
#include <pragma/datatypes_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/exec_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/render_lib.h>
#include <pragma/utility_lib.h>
#include <cybergraphx/cybergraphics.h>
#include <datatypes/pictureclass.h>
#include <dos/dostags.h>
#include <exec/memory.h>
#include <intuition/icclass.h>
#include <stdio.h>
#include <string.h>
struct Arg1
{
long *mode,*res,*dither,*depth;
};
struct Arg2
{
long mode,res,dither,depth;
};
extern Library *SuperClassBase,*RenderBase;
static void ReadPrefs(Arg2 *arg)
{
char *var;
arg->mode=1;
arg->res=2;
arg->dither=0;
arg->depth=8;
if(var=(char *)AllocVec(256,0))
{
if(GetVar("ENV:DataTypes/pcd.prefs",var,256,LV_VAR|GVF_GLOBAL_ONLY)>=0)
{
RDArgs *rdargs;
if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
{
RDArgs *args;
Arg1 para={0,0,0,0};
rdargs->RDA_Source.CS_Buffer=var;
rdargs->RDA_Source.CS_Length=strlen(var);
rdargs->RDA_Source.CS_CurChr=0;
if(args=ReadArgs("MODE/A/N,RESOLUTION/A/N,DITHER/A/N,DEPTH/A/N",(long *)¶,rdargs))
{
if(para.mode)
{
arg->mode=*para.mode;
if(arg->mode<0) arg->mode=0;
else if(arg->mode>1) arg->mode=1;
}
if(para.res)
{
arg->res=*para.res;
if(arg->res<0) arg->res=0;
else if(arg->res>5) arg->res=5;
}
if(para.dither)
{
arg->dither=*para.dither;
if(arg->dither<0) arg->dither=0;
else if(arg->dither>1) arg->dither=1;
}
if(para.depth)
{
arg->depth=*para.depth;
if(arg->depth<3) arg->depth=3;
else if(arg->depth>8) arg->depth=8;
}
FreeArgs(args);
}
FreeDosObject(DOS_RDARGS,rdargs);
}
}
FreeVec(var);
}
if(SuperClassBase->lib_Version!=43) arg->mode=0;
}
ULONG Colors2DT(Object *obj,UBYTE *color)
{
UBYTE *cr;
ULONG *cregs,i,num,error=0;
GetDTAttrs(obj,PDTA_NumColors,&num,PDTA_ColorRegisters,&cr,PDTA_CRegs,&cregs,TAG_END);
if(cr&&cregs)
{
for(i=0;i<num;i++,cr+=3,cregs+=3,color+=4)
{
cr[0]=color[1];
cr[1]=color[2];
cr[2]=color[3];
cregs[0]=cr[0]<<24;
cregs[1]=cr[1]<<24;
cregs[2]=cr[2]<<24;
}
}
else error=ERROR_NO_FREE_STORE;
return error;
}
static ULONG ReadP6(Object *obj,BitMapHeader *bh,BitMap *bm,BPTR file,Arg2 *arg)
{
ULONG error=0;
UBYTE *rgb;
if(rgb=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height*4,MEMF_CLEAR))
{
UBYTE *buffer;
if(buffer=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
{
UWORD y;
UBYTE *p1=rgb;
for(y=0;y<bh->bmh_Height;y++)
{
UWORD x;
UBYTE *p2=buffer;
if(Read(file,buffer,bh->bmh_Width*3)!=bh->bmh_Width*3)
{
error=DTERROR_NOT_ENOUGH_DATA;
break;
}
for(x=0;x<bh->bmh_Width;x++,p1+=4,p2+=3)
{
p1[1]=p2[0];
p1[2]=p2[1];
p1[3]=p2[2];
}
}
FreeVec(buffer);
if(!error)
{
APTR rmh;
if(rmh=CreateRMHandler(RND_MemType,RMHTYPE_POOL,TAG_END))
{
ULONG *palette;
if(palette=CreatePalette(RND_RMHandler,rmh,TAG_END))
{
APTR hst;
if(hst=CreateHistogram(RND_RMHandler,rmh,TAG_END))
{
if(AddRGBImage(hst,(ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,TAG_END)==ADDH_SUCCESS)
{
if(ExtractPalette(hst,palette,1<<bh->bmh_Depth,TAG_END)==EXTP_SUCCESS)
{
UBYTE *chunky;
if(chunky=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height,0))
{
if(Render((ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,chunky,palette,RND_DitherMode,arg->dither,TAG_END)==REND_SUCCESS)
{
UBYTE *color;
if(color=(UBYTE *)AllocVec((1<<bh->bmh_Depth)*4,0))
{
ExportPalette(palette,color,TAG_END);
if(!(error=Colors2DT(obj,color))) Chunky2BitMap(chunky,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
FreeVec(color);
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
FreeVec(chunky);
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
DeleteHistogram(hst);
}
else error=ERROR_NO_FREE_STORE;
DeletePalette(palette);
}
else error=ERROR_NO_FREE_STORE;
DeleteRMHandler(rmh);
}
else error=ERROR_NO_FREE_STORE;
}
}
else error=ERROR_NO_FREE_STORE;
FreeVec(rgb);
}
else error=ERROR_NO_FREE_STORE;
return error;
}
static ULONG ReadP6_V43(Object *obj,BitMapHeader *bh,BPTR file)
{
ULONG error=0,len=bh->bmh_Width*bh->bmh_Height*3;
UBYTE *pix;
if(pix=(UBYTE *)AllocVec(len,0))
{
if(Read(file,pix,len)==len) DoMethod(obj,PDTM_WRITEPIXELARRAY,pix,RECTFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
else error=DTERROR_NOT_ENOUGH_DATA;
FreeVec(pix);
}
else if(pix=(UBYTE *)AllocVec(bh->bmh_Width*3,0))
{
UWORD y;
for(y=0;y<bh->bmh_Height;y++)
{
if(Read(file,pix,bh->bmh_Width*3)!=bh->bmh_Width*3)
{
error=DTERROR_NOT_ENOUGH_DATA;
break;
}
DoMethod(obj,PDTM_WRITEPIXELARRAY,pix,RECTFMT_RGB,bh->bmh_Width*3,0,y,bh->bmh_Width,1);
}
FreeVec(pix);
}
else error=ERROR_NO_FREE_STORE;
return error;
}
static ULONG ReadNum(BPTR file)
{
ULONG retval=0;
for(;;)
{
char c;
if(Read(file,&c,1)!=1) return 0;
if(c==10||c==32) break;
retval*=10;
retval+=c-'0';
}
return retval;
}
static ULONG GetPicture(IClass *cl,Object *obj)
{
ULONG error=0;
BPTR nil;
if(nil=Open("NIL:",MODE_OLDFILE))
{
char *fname,*dname,tmp[L_tmpnam];
Arg2 arg;
ReadPrefs(&arg);
GetDTAttrs(obj,DTA_Name,&dname,TAG_END);
if(dname)
{
SetDTAttrs(obj,0,0,DTA_ObjName,dname,TAG_END);
tmpnam(tmp);
strncpy(tmp,"PIPE:",5);
if(fname=(char *)AllocVec(strlen(dname)+L_tmpnam+50,0))
{
SPrintf(fname,"run pcdtoppm >%s -%lu -ppm \"%s%\"",tmp,arg.res+1,dname);
if(Execute(fname,nil,nil)!=DOSFALSE)
{
BPTR file;
if(file=Open(tmp,MODE_OLDFILE))
{
BitMapHeader *bh;
char head[3];
GetDTAttrs(obj,PDTA_BitMapHeader,&bh,TAG_END);
if(bh)
{
if(Read(file,head,3)==3)
{
bh->bmh_Width=ReadNum(file);
bh->bmh_PageWidth=bh->bmh_Width;
bh->bmh_Height=ReadNum(file);
bh->bmh_PageHeight=bh->bmh_Height;
bh->bmh_Compression=1;
ReadNum(file);
if(!arg.mode)
{
if(RenderBase)
{
BitMap *bm;
bh->bmh_Depth=arg.depth;
SetDTAttrs(obj,0,0,DTA_NominalHoriz,bh->bmh_Width,DTA_NominalVert,bh->bmh_Height,PDTA_NumColors,1<<arg.depth,TAG_END);
if(bm=AllocBitMap(bh->bmh_Width,bh->bmh_Height,bh->bmh_Depth,BMF_CLEAR|BMF_STANDARD|BMF_DISPLAYABLE,0))
{
SetDTAttrs(obj,0,0,PDTA_ModeID,BestModeID(BIDTAG_NominalWidth,bh->bmh_Width,BIDTAG_NominalHeight,bh->bmh_Height,BIDTAG_Depth,bh->bmh_Depth,TAG_END),PDTA_BitMap,bm,TAG_END);
error=ReadP6(obj,bh,bm,file,&arg);
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NOT_IMPLEMENTED;
}
else
{
bh->bmh_Depth=24;
SetDTAttrs(obj,0,0,DTA_ErrorNumber,&error,DTA_NominalHoriz,bh->bmh_Width,DTA_NominalVert,bh->bmh_Height,PDTA_ModeID,0,PDTA_SourceMode,PMODE_V43,TAG_END);
if(!error) error=ReadP6_V43(obj,bh,file);
}
}
else error=DTERROR_NOT_ENOUGH_DATA;
}
else error=ERROR_NO_FREE_STORE;
Close(file);
}
else error=IoErr();
}
else error=IoErr();
FreeVec(fname);
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
Close(nil);
}
else error=IoErr();
return error;
}
static ULONG mNew(IClass *cl,Object *obj,opSet *msg)
{
TagItem *ti;
if(ti=FindTagItem(DTA_SourceType,msg->ops_AttrList))
{
if(ti->ti_Data!=DTST_FILE&&ti->ti_Data!=DTST_CLIPBOARD&&ti->ti_Data!=DTST_RAM)
{
SetIoErr(ERROR_OBJECT_WRONG_TYPE);
return 0;
}
}
if(obj==(Object *)cl)
{
if(obj=(Object *)DoSuperMethodA(cl,obj,Msg(msg)))
{
ULONG error;
if(error=GetPicture(cl,obj))
{
SetIoErr(error);
CoerceMethod(cl,obj,OM_DISPOSE);
obj=0;
}
}
}
else
{
SetIoErr(ERROR_NOT_IMPLEMENTED);
obj=0;
}
return ULONG(obj);
}
static ULONG mSet(IClass *cl,Object *obj,opSet *msg)
{
ULONG retval;
if(retval=DoSuperMethodA(cl,obj,Msg(